package com.sv.utils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.apache.commons.lang.ClassUtils;

public class ReflectUtils {

//	public static void copyProperties(Object obj1, Object obj2) {
//		if (null == obj1) {
//			throw new RuntimeException("target obj can not be null!");
//		}
//
//		if (null != obj2) {
//			Field[] fields = obj2.getClass().getDeclaredFields();
//			for (Field f : fields) {
//				String fieldName = f.getName();
//
//				try {
//					Method getFiledValue = obj2.getClass().getMethod(
//							"get" + fieldName.substring(0, 1).toUpperCase()
//									+ fieldName.substring(1), null);
//					Field rf = obj1.getClass().getDeclaredField(fieldName);
//					rf.setAccessible(true);
//					rf.set(obj1, getFiledValue.invoke(obj2, null));
//				} catch (Exception e) {
//					continue;
//				}
//			}
//		}
//	}

	public static Object invoke(Object obj, String method) {
		try {
			Method m = obj.getClass().getMethod(method);

			m.setAccessible(true);

			return m.invoke(obj);
		} catch (Exception e) {
			throwBuildExcpetion(e);
			return null;
		}
	}

	public static Object invoke(Object obj, String method, Class argType,
			Object arg) {
		try {
			Method m = obj.getClass()
					.getMethod(method, new Class[] { argType });

			m.setAccessible(true);

			return m.invoke(obj, new Object[] { arg });
		} catch (Exception e) {
			throwBuildExcpetion(e);
			return null;
		}
	}

	public static Object getFiledValue(Object obj, String filedName) {
		try {
			Field f = obj.getClass().getField(filedName);
			f.setAccessible(true);
			return f.get(obj);

		} catch (Exception e) {
			throwBuildExcpetion(e);
			return null;
		}
	}

	public static Object cloneObjectByClass(Object obj, Class clazz) {

		try {
			Object newObj = clazz.newInstance();
			copyProperties(obj, newObj);
			return newObj;
		} catch (Exception e) {
			throwBuildExcpetion(e);
			return null;
		}
	}

	public static void copyProperties(Object obj, Object dest) {
		Class clazz = dest.getClass();
		try {
			copyProperties(obj, dest, clazz);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}

	public static void copyProperties(Object obj, Object dest, Class clazz)
			throws IllegalArgumentException, IllegalAccessException,
			InvocationTargetException {
		Method[] methods = clazz.getMethods();
		for (Method m : methods) {
			if (m.getName().startsWith("set")) {
				String fieldName = m.getName().replaceFirst("set", "");
				Method getMethod = fieldGetMethod(obj, fieldName);
				invoke(dest, m.getName(), m.getParameterTypes()[0],
						getMethod.invoke(obj));
			}
		}
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static Method fieldGetMethod(Object obj, String field) {
		Class clazz = obj.getClass();

		String methodName = "get" + field.substring(0, 1).toUpperCase()
				+ field.substring(1);

		Method method = null;
		try {
			method = clazz.getMethod(methodName);

		} catch (Exception e) {

			throwBuildExcpetion(e);
		}
		return method;
	}

	public static Object newInstance(Object obj) {
		if (obj == null) {
			return null;
		}
		try {
			return ClassUtils.getClass(obj.getClass().getName()).newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}

	private static void throwBuildExcpetion(Exception e) {
		throw new RuntimeException(e);
	}

	// public static void main(String[] args) {
	// UserInfo a = new UserInfo();
	// a.setAge(10);
	// a.setEmail("huyuehan@madie-.com");
	// UserInfo b = new UserInfo();
	// ReflectUtils.copyProperties(b, a);
	// System.out.println(b.getAge());
	// }
}
